//题目:
// 给你一个整数数组nums和两个整数firstLen和secondLen,返回两个非重叠子数组中元素的最大和，长度分别为firstLen和secondLen。
// 长度为 firstLen 的子数组可以出现在长为 secondLen 的子数组之前或之后，但二者必须是不重叠的。
// 子数组是数组的一个 连续 部分。

// 示例 1：
// 输入：nums = [0,6,5,2,2,5,1,9,4], firstLen = 1, secondLen = 2
// 输出：20
// 解释：子数组的一种选择中，[9] 长度为 1，[6,5] 长度为 2。

// 示例 2：
// 输入：nums = [3,8,1,3,2,1,8,9,0], firstLen = 3, secondLen = 2
// 输出：29
// 解释：子数组的一种选择中，[3,8,1] 长度为 3，[8,9] 长度为 2。

// 示例 3：
// 输入：nums = [2,1,5,6,0,9,5,0,3,8], firstLen = 4, secondLen = 3
// 输出：31
// 解释：子数组的一种选择中，[5,6,0,9] 长度为 4，[0,3,8] 长度为 3。
 
// 提示：
// 1 <= firstLen, secondLen <= 1000
// 2 <= firstLen + secondLen <= 1000
// firstLen + secondLen <= nums.length <= 1000
// 0 <= nums[i] <= 1000
#include<iostream>
#include<numeric>
#include<vector>

using namespace std;
//代码
class Solution 
{
public:
    int Find_Max(const vector<int>& nums,int begin,int end,int len)
    {
        //在nums的[begin,end]中，找出长度为len的、元素和最大的子数组
        int sum=0;
        for(int i=begin;i<begin+len;i++)
            sum+=nums[i];//第一个长度为len的子数组和
        int ret=sum;
        for(int i=begin+len;i<=end;i++)
            sum+=(nums[i]-nums[i-len]),ret=max(ret,sum);
        return ret;
    }
    int maxSumTwoNoOverlap(vector<int>& nums, int firstLen, int secondLen) 
    {
        //法一：分割点+定长子数组求和
        // int less_len=min(firstLen,secondLen),greater_len=max(firstLen,secondLen);
        // int ret=0;
        // for(int i=less_len-1;i<nums.size()-less_len;i++)
        // {
        //     //以i为分割点，在[0,i]、[i+1,size-1]中找两个和最大的子数组
        //     int sum1=0,sum2=0;
        //     if(i+1>=greater_len && nums.size()-i-1>=greater_len)
        //     {
        //         sum1=Find_Max(nums,0,i,firstLen)+Find_Max(nums,i+1,nums.size()-1,secondLen);
        //         sum2=Find_Max(nums,0,i,secondLen)+Find_Max(nums,i+1,nums.size()-1,firstLen);
        //     }
        //     else if(i+1<greater_len && nums.size()-i-1>=greater_len)
        //         sum1=Find_Max(nums,0,i,less_len)+Find_Max(nums,i+1,nums.size()-1,greater_len);
        //     else if(i+1>=greater_len && nums.size()-i-1<greater_len)
        //         sum2=Find_Max(nums,0,i,greater_len)+Find_Max(nums,i+1,nums.size()-1,less_len);

        //     ret=max({ret,sum1,sum2});
        // }
        // return ret;

        //法二：动态规划+滑动窗口
        return max(help(nums, firstLen, secondLen), help(nums, secondLen, firstLen));
    }
    int help(vector<int>& nums, int firstLen, int secondLen) { //固定firstlen与secondlen
        int suml = accumulate(nums.begin(), nums.begin() + firstLen, 0);
        int maxSumL = suml;
        int sumr = accumulate(nums.begin() + firstLen, nums.begin() + firstLen + secondLen, 0);
        int res = maxSumL + sumr;
        for (int i = firstLen + secondLen, j = firstLen; i < nums.size(); ++i, ++j) {
            suml += nums[j] - nums[j - firstLen];
            maxSumL = max(maxSumL, suml);
            sumr += nums[i] - nums[i - secondLen];
            res = max(res, maxSumL + sumr);
        }
        return res;
    }
};